package com.yunchao.app.presentation.main

import android.os.Bundle
import android.text.InputType
import android.view.KeyEvent
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import androidx.core.view.MenuProvider
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavController
import androidx.navigation.NavDestination
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.NavigationUI
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import by.kirich1409.viewbindingdelegate.viewBinding
import com.seuic.scankey.IKeyEventCallback
import com.seuic.scankey.ScanKeyService
import com.yunchao.app.R
import com.yunchao.app.databinding.ActivityNavHostBinding
import com.yunchao.app.presentation.configure.ConfigureActivity.Companion.openConfigure
import com.yunchao.feature.base.presentation.activity.BaseActivity
import com.yunchao.feature.base.presentation.activity.BaseKeyEventFragment
import com.yunchao.feature.base.presentation.ext.hideLoadingDialog
import com.yunchao.feature.base.presentation.ext.navigateSafe
import com.yunchao.feature.base.presentation.ext.showInputDialog
import com.yunchao.feature.base.presentation.ext.showLoadingDialog
import com.yunchao.feature.base.presentation.ext.showTipDialog
import com.yunchao.feature.base.presentation.ext.toast
import com.yunchao.feature.base.presentation.nav.NavManager
import com.yunchao.feature.business.presentation.screen.info.BusinessInfoFragment
import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.viewModel
import kotlin.getValue
import kotlin.system.exitProcess

class NavHostActivity : BaseActivity(R.layout.activity_nav_host),
    NavController.OnDestinationChangedListener {

    private val viewModel: NavHostViewModel by viewModel()

    private val binding: ActivityNavHostBinding by viewBinding()
    private lateinit var appBarConfiguration: AppBarConfiguration
    private val navManager: NavManager by inject()

    private val menuProvider: MenuProvider by lazy {
        object : MenuProvider {
            override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
                menuInflater.inflate(R.menu.toolbar_menu, menu)
            }

            override fun onMenuItemSelected(menuItem: MenuItem): Boolean =
                if (menuItem.itemId == R.id.action_add) {
                    openConfigure(this@NavHostActivity, true)
                    true
                } else {
                    false
                }
        }
    }

    private val scanKeyService: ScanKeyService by inject()

    override fun onCreate(savedInstanceState: Bundle?) {
        scanKeyService.registerCallback(mCallback, "250")
        super.onCreate(savedInstanceState)
        initNavManager()
        initBottomNavigation()

        addMenuProvider(menuProvider)

        lifecycleScope.launch { viewModel.uiEffectFlow.collect(::sideEffect) }
    }

    private fun sideEffect(effect: NavHostViewModel.UiEffect) {
        when (effect) {
            is NavHostViewModel.UiEffect.ShowToast -> toast(effect.msg)
            is NavHostViewModel.UiEffect.ShowLoading -> showLoadingDialog()
            is NavHostViewModel.UiEffect.HideLoading -> hideLoadingDialog()
            is NavHostViewModel.UiEffect.ShowDialog -> showTipDialog(content = effect.msg) {
                (getCurrentFragment() as? BusinessInfoFragment)?.getBusinessInfo()
            }
        }
    }

    private fun initNavManager() {
        navManager.setOnNavEvent { getCurrentFragment()?.navigateSafe(it) }
    }

    private fun initBottomNavigation() {
        // When using FragmentContainerView, NavController fragment can't be retrieved by using `findNavController()`
        // See https://stackoverflow.com/questions/59275009/fragmentcontainerview-using-findnavcontroller/59275182#59275182
        // See https://issuetracker.google.com/issues/142847973
        val navController = binding.navHostFragment.getFragment<NavHostFragment>().navController
        navController.addOnDestinationChangedListener(this)
        setSupportActionBar(binding.baseToolbar)

        appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.businessNavGraph, R.id.lockNavGraph
            )
        )
        setupActionBarWithNavController(navController, appBarConfiguration)
        binding.bottomNav.setupWithNavController(navController)
    }

    private fun getCurrentFragment(): Fragment? {
        val navHostFragment = supportFragmentManager.findFragmentById(R.id.navHostFragment)
        val currentFragment = navHostFragment?.childFragmentManager?.primaryNavigationFragment
        return currentFragment
    }

    override fun onSupportNavigateUp(): Boolean {
        val navController = binding.navHostFragment.getFragment<NavHostFragment>().navController
        return NavigationUI.navigateUp(navController, appBarConfiguration) || super.onNavigateUp()
    }


    override fun onDestinationChanged(
        controller: NavController,
        destination: NavDestination,
        arguments: Bundle?
    ) {
        when (destination.label) {
            getString(com.yunchao.feature.base.R.string.功能区),
            getString(com.yunchao.feature.base.R.string.业务区) -> {
                binding.bottomNav.visibility = View.VISIBLE
            }

            else -> {
                binding.bottomNav.visibility = View.GONE
            }
        }
    }

    override fun onStart() {
        super.onStart()
        viewModel.openDevice()
    }

    override fun onStop() {
        super.onStop()
        viewModel.closeDevice()
    }

    override fun onDestroy() {
        scanKeyService.unregisterCallback(mCallback)
        super.onDestroy()
    }

    private var firstTime: Long = 0L


    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        if (keyCode == KeyEvent.KEYCODE_BACK) {// 点击了返回按键
            exitApp()// 退出应用
            return true;
        }
        return super.onKeyDown(keyCode, event)
    }

    private fun exitApp() {
        if (System.currentTimeMillis() - firstTime <= EXIT_APP_TIME) {
            // 双击确认退出
            showInputDialog(
                title = getString(com.yunchao.feature.base.R.string.提示),
                content = getString(com.yunchao.feature.base.R.string.是否退出应用),
                defaultContent = getString(com.yunchao.feature.base.R.string.请输入密码),
                inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_PASSWORD
            ) { content ->
                if (content.isNullOrBlank()) {
                    toast(getString(com.yunchao.feature.base.R.string.请输入密码))
                    return@showInputDialog
                }
                if (content != "314159") {
                    toast(getString(com.yunchao.feature.base.R.string.请输入正确的密码))
                    return@showInputDialog
                }
                // 正确密码，退出应用
                finishAffinity()  // 关闭所有 Activity
                android.os.Process.killProcess(android.os.Process.myPid())  // 杀死当前进程
            }
        } else {
            // 首次点击，记录时间
            firstTime = System.currentTimeMillis()
            toast("再按一次退出应用")  // 提示用户双击
        }
    }


    private val mCallback: IKeyEventCallback = object : IKeyEventCallback.Stub() {
        override fun onKeyDown(p0: Int) {
            (getCurrentFragment() as? BaseKeyEventFragment)?.onceScanLock()
        }

        override fun onKeyUp(p0: Int) {
            (getCurrentFragment() as? BaseKeyEventFragment)?.onStopScanLock()
        }

    }


    companion object {
        private const val EXIT_APP_TIME: Long = 2000L
    }
}